优化LLVM IR后，使用所选的LLVM目标生成机器码。其中，以下任务在后端执行:\par

\begin{enumerate}
\item 构造了用于指令选择的有向无环图(DAG)，通常称为SelectionDAG。
\item 选择与IR代码相对应的机器指令。
\item 选定的机器指令按最优顺序排列。
\item 机器寄存器取代虚拟寄存器。
\item 函数中添加头尾代码。
\item 按最优顺序排列基本块。
\item 运行目标特定的Pass。
\item 使用对象源码或汇编进行触发。
\end{enumerate}

所有这些步骤都是由MachineFunctionPass类派生的机器函数Pass来实现的。这是FunctionPass类的一个子类，该类是旧Pass管理器使用的基类之一。在LLVM 12中，机器功能Pass到新Pass管理器的转换仍在进行中。\par

在所有这些步骤中，LLVM指令都要进行转换。在代码层，一个LLVM IR指令由Instruction类的实例表示。在指令选择阶段，它转换为MachineInstr实例。这是一个更接近实际机器表示。它已经包含了对目标有效的指令，但仍然在虚拟寄存器上操作(到寄存器分配)，还可以包含某些伪指令。指令选择之后的传递会对其进行改进，最后创建MCInstr实例，它是真实机器指令的表示。MCInstr实例可以写入目标文件或打印为汇编代码。\par

为了探索后端Pass，可以创建一个包含以下内容的小IR文件:\par

\begin{tcolorbox}[colback=white,colframe=black]
define i16 @sum(i16 \%a, i16 \%b) \{ \\
\hspace*{0.5cm}\%res = add i16 \%a, 3 \\
\hspace*{0.5cm}ret i16 \%res \\
\}
\end{tcolorbox}

将此代码保存为sum.ll，使用llc(LLVM静态编译器)编译MIPS架构。该工具将LLVM IR编译为汇编文本或目标文件。可以在命令行中用-mtriple选项覆盖编译的目标平台。使用-debug-pass=\allowbreak Structure选项调用llc工具:\par

\begin{tcolorbox}[colback=white,colframe=black]
\$ llc -mtriple=mips-linux-gnu -debug-pass=Structure < sum.ll
\end{tcolorbox}

除了生成的程序集代码之外，您还将看到一长串要运行的机器Pass列表。其中，MIPS DAG->DAG指令选择模式Pass执行指令选择，MIPS延迟槽填充器是针对特定目标的Pass，清理前的最后一个Pass是MIPS汇编打印器负责打印汇编代码。在所有这些Pass中，指令选择Pass是最有趣的，我们将在下一节详细讨论它。\par












